#ifndef ee5bd5dc8195c6801c03e4e45c950c9b
#define ee5bd5dc8195c6801c03e4e45c950c9b

#include "base.h"
#include "prefix.hpp"

class CTrieNode {
    private: 
        Prefix prefix;
        uint32_t asn;
        CTrieNode * nodes[2];
        bool is_set;

    public:
        CTrieNode(); 

        CTrieNode(uint32_t _asn, uint32_t prefix_ip, uint8_t prefix_netmask); 

        ~CTrieNode(); 

        Prefix getPrefix(); 
        void setPrefix(Prefix _prefix); 

        uint32_t getAsn(); 
        void setASN(uint32_t _asn ) ; 

        bool isSet(); 
        void isSet(bool x); 

        CTrieNode * getNode( int i ); 
        void setNode( int i, CTrieNode * node ); 

        string str();
};

/*
    -- CTrieTree
 */

class CTrieTree {
    private:
        CTrieNode * root;
        uint32_t stats_nodes_all;
        uint32_t stats_nodes_set;

    public:
        static const uint32_t NONE              = 0;
        static const uint32_t FORCENODE         = 1;

        static const int ERR_OK                 = 0;
        static const int ERR_TRIE_FILE_OPEN     = -1;
        static const int ERR_LEAF_PRESENT       = -2;
        static const int ERR_PROBLEM_WITH_LINE  = -3;
        static const int ERR_TRIE_FILE_FORMAT   = -4;

    public:
        CTrieTree(); 
        ~CTrieTree(); 

        int insertNode( uint32_t asn, Prefix prefix, uint32_t flags=CTrieTree::NONE ); 

        CTrieNode * lpmatch( uint32_t ip , uint8_t mask = 32); 

        inline CTrieNode * lpmatch( struct in_addr a )
        {
            uint32_t t = a.s_addr;
            return lpmatch( bytes_4_to_uint32( BYTE0(t), BYTE1(t), BYTE2(t), BYTE3(t) ) );
        }

        void addSpecial(); 

        int addFromFile( string fname, uint32_t format, uint32_t flags=CTrieTree::FORCENODE ); 

        uint32_t getStatsNodesAll(); 
        uint32_t getStatsNodesSet(); 

        /** ** static ** **/
        static const uint32_t FORMATTXT = 1;

        static CTrieTree * newFromFile( string fname, uint32_t format ); 

        static void addReservedPrefixes( CTrieTree * t ); 
};


#endif // EOF
